package top.z.template.interpreter;

/**
 * 用于{@link AstInterpreter}访问对象的字段和方法.
 * 这是一个由所有{@link AstInterpreter}实例使用的单例类.
 * 通过 setInstance 替换默认实现, 实现必须是线程安全的.
 */
public abstract class Reflection {

    private static Reflection instance = new JavaReflection();

    public synchronized static void setInstance(Reflection reflection) {
        instance = reflection;
    }

    public synchronized static Reflection getInstance() {
        return instance;
    }

    /**
     * 获取指定对象的字段.
     */
    public abstract Object getField(Object obj, String name);

    /**
     * 如果object是Class的实例, 则返回匹配的静态方法.
     * 如果方法名称为null, 并且该对象是{@link FunctionalInterface}, 则返回该对象上声明的第一个方法.
     *
     * @param object   对象
     * @param name     方法名称
     * @param argument 传入的参数
     * @return object
     */
    public abstract Object getMethod(Object object, String name, Object... argument);

    /**
     * 返回对象中字段的值, 调用之前必须已通过{@link #getField}检索.
     *
     * @param object 对象
     * @param field  字段
     * @return object
     */
    public abstract Object getFieldValue(Object object, Object field);

    /**
     * 调用对象的方法, 调用之前必须已通过{@link #getMethod}检索.
     *
     * @param object   对象
     * @param method   方法
     * @param argument 传入的参数
     * @return object
     */
    public abstract Object callMethod(Object object, Object method, Object... argument);

}
